package nl.tue.be.ds.duraark.bSDD;

import java.util.HashSet;
import java.util.Iterator;

import org.codehaus.jackson.JsonNode;

import com.db4o.Db4oEmbedded;
import com.db4o.ObjectContainer;
import com.db4o.ObjectSet;
import com.db4o.config.EmbeddedConfiguration;
import com.db4o.query.Query;

public class DataBaseUtilities {
	
	public static ObjectContainer db;
	//public static final String stringGuidForRelOverflow = "RelOverflow";
	
	public static void setupDatabase(String databaseName){
		
		db = Db4oEmbedded.openFile(databaseConfiguration(), databaseName);
	}
	
	private static EmbeddedConfiguration  databaseConfiguration(){
		
		EmbeddedConfiguration db4oConfig = Db4oEmbedded.newConfiguration();	
		db4oConfig.common().activationDepth(10);
		db4oConfig.common().updateDepth(10);
		db4oConfig.common().objectClass(DataBaseStorageUnit.class).objectField("guid").indexed(true);
		db4oConfig.common().bTreeNodeSize(256);
		return db4oConfig;
	}
	
	public static boolean isConceptExistedInDB(JsonNode conceptJsonNode, ObjectContainer db) {

		String singleConceptGuid = conceptJsonNode.get("guid").getTextValue();
		Query query = db.query();
		query.constrain(DataBaseStorageUnit.class);
		query.descend("guid").constrain(singleConceptGuid);
		ObjectSet<DataBaseStorageUnit> result = query.execute();
		return result.size() > 0;
	}
	
	public static boolean isConceptExistedInDB(String singleConceptGuid, ObjectContainer db) {

		Query query = db.query();
		query.constrain(DataBaseStorageUnit.class);
		query.descend("guid").constrain(singleConceptGuid);
		ObjectSet<DataBaseStorageUnit> result = query.execute();
		return result.size() > 0;
	}
	
	public static HashSet<String> getAllValidDumpedRelType(ObjectContainer db){
		HashSet<String> RelTypeSet = new HashSet<String>();
		Query query = db.query();
		query.constrain(DataBaseStorageUnit.class);
		
		ObjectSet<DataBaseStorageUnit> dbsuSet = query.execute();
		
		Iterator<DataBaseStorageUnit> i = dbsuSet.iterator();
		while(i.hasNext()){
			DataBaseStorageUnit dbSU = i.next();
			if (dbSU.getParentsGuidMap()!=null)
				RelTypeSet.addAll(dbSU.getParentsGuidMap().values());
			if (dbSU.getChildrenGuidMap()!=null)
				RelTypeSet.addAll(dbSU.getChildrenGuidMap().values());	
		}
		
		return RelTypeSet;
	}
	
	public static HashSet<String> getAllValidDumpedRelGuid(ObjectContainer db){
		HashSet<String> guidSet = new HashSet<String>();
		
		//HashMap<String, String> exampleMap = new HashMap<String, String>();
		
		Query query = db.query();
		query.constrain(DataBaseStorageUnit.class);
		
		/*query.descend("parentsGuidMap").constrain(exampleMap)
			.or(query.descend("childrenGuidMap").constrain(exampleMap));*/
		
		ObjectSet<DataBaseStorageUnit> dbsuSet = query.execute();
		
		Iterator<DataBaseStorageUnit> i = dbsuSet.iterator();
		while(i.hasNext()){
			DataBaseStorageUnit dbSU = i.next();
			if (dbSU.getParentsGuidMap()!=null)
				guidSet.addAll(dbSU.getParentsGuidMap().keySet());
			if (dbSU.getChildrenGuidMap()!=null)
				guidSet.addAll(dbSU.getChildrenGuidMap().keySet());	
		}
		
		return guidSet;
	}
	
	public static DataBaseStorageUnit getDumpedDBSunitPerGuid(String conceptGuid, ObjectContainer db){
		
		Query query = db.query();
		query.constrain(DataBaseStorageUnit.class);
		query.descend("guid").constrain(conceptGuid);
		ObjectSet<DataBaseStorageUnit> result = query.execute();
		
		return result.get(0);
	}
	
	public static HashSet<DataBaseStorageUnit> getAllDumpedDBSunit(ObjectContainer db){
		HashSet<DataBaseStorageUnit> hs = new HashSet<DataBaseStorageUnit>();
		Query query = db.query();
		query.constrain(DataBaseStorageUnit.class);
		ObjectSet<DataBaseStorageUnit> result = query.execute();
		hs.addAll(result);
		return hs;
	}
	
}
